﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using ArkanoidX.Objects;

namespace ArkanoidX
{
    public class LevelBuilder : IComparable<LevelBuilder>
    {
        public int _levelNumber;
        public String _password;
        public String _content;

        public LevelManager _manager;
        public MainGame _game;
        public Rectangle _arenaArea;


        /**
         * objects inside the level to create
         */
        public Bricks _bricks;
        public Racket _racket;
        public Ball _ball;


        public bool _loaded = false;


        public int LevelNumber
        {
            get { return _levelNumber; }
        }


        public LevelBuilder(LevelManager manager, int levelNumber, String password, String content)
        {
            _manager = manager;
            _game = manager.Game;
            _arenaArea = manager.ArenaArea;

            _levelNumber = levelNumber;
            _password = password;
            _content = content;
        }


        public bool Load()
        {
            if (_loaded)
            {
                return true;
            }

            _bricks = null;
            _racket = null;
            _ball = null;

            /**
             * load the level layout file to create bricks and enemies (if supported in this version)
             */

            ConfigParser cp = new ConfigParser(_content);
            int numOfRows = int.MaxValue;   // set to maximum value if not specified
            int brickXStart = 0;    /* specifying the number of bricks on the left to shift by to load the first brick */
            int brickYStart = 0;    /* specifying the number of bricks above the first brick to load */

            while (!cp.EndOfString)
            {
                int ip;
                string line = cp.ReadLine();

                if (cp.IsCurrentLineParsable)
                {
                    String varName = cp.VarName;
                    String varValue = cp.VarValue;

                    switch (varName)
                    {
                        case "rows_of_bricks":
                            numOfRows = int.Parse(varValue);
                            break;
                        case "brick_x_start":
                            brickXStart = int.Parse(varValue);
                            break;
                        case "brick_y_start":
                            brickYStart = int.Parse(varValue);
                            break;
                    }
                }
                else
                {   /* not in standard variable definition format */
                    if ((ip = Utility.CompareString(line, "bricks")) >= 0)
                    {   /* arrangement of bricks */
                        _bricks = new Bricks(_game, _arenaArea);
                        StringBuilder sb = new StringBuilder();
                        /**
                         * read until the end of the content string
                         */
                        while (!cp.EndOfString)
                        {
                            line = cp.ReadLine();
                            if (line == null || (ip = Utility.CompareString(line, "end_of_bricks")) >= 0)
                            {
                                break;
                            }
                            sb.Append(line);
                            sb.Append('\n');
                        }
                        _bricks.LoadFromString(sb.ToString(), numOfRows, brickXStart, brickYStart);
                    }
                }
            }

            if (_bricks == null)
            {
                return false;
            }


            /**
             * <summary>
             *  create the racket
             * </summary>
             * 
             * <remarks>
             *  Although in this game racket is somewhat level-independent
             *  we still create it here for each level individually
             * 
             *  for now, there is nothing in the level file specially set up for 
             *  racket building
             * </remarks>
             */

            /**
             * derive size of the racket from the size of brick
             */
            _racket = new Racket(_game, _arenaArea, _bricks);
            _racket.PutInStartPosition();

            if (_racket == null)
            {
                return false;
            }

            /**
             * create ball
             */
            _ball = new Ball(_game, _arenaArea, _bricks, _racket);
            _ball.PutInStartPosition();

            if (_ball == null)
            {
                return false;
            }

            return true;
        }

        public Level Build()
        {
            if (!Load())
            {
                return null;
            }

            Level newLevel = new Level(this._game, this._levelNumber, 
                _bricks, _racket, _ball);

            return newLevel;
        }

        public int CompareTo(LevelBuilder that)
        {
            return this._levelNumber.CompareTo(that._levelNumber);
        }

        public bool CheckPassword(String password)
        {
            if (this._password == null)
            {
                return true;
            }
            return this._password == password;
        }

    }
}
